package com.df.base.updater.impl;

import com.df.base.common.GameReqScriptManager;
import com.df.base.common.GameRequestMapping;
import com.df.base.common.IScript;
import com.df.base.other.FileUtils;
import com.df.base.other.SpringContextHelper;
import com.df.base.updater.AbstractGroovyUpdater;
import com.df.base.updater.GroovyUpdateContext;
import com.df.base.updater.IGroovyUpdater;
import groovy.lang.GroovyClassLoader;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Logger;

/**
 * 本地开发使用的脚本更新
 */
@Profile("dev")
@Slf4j
@ConditionalOnMissingBean(DevGroovyUpdater.class)
public class DevGroovyUpdater extends AbstractGroovyUpdater {


    /**
     * 脚本上次更新的时间
     */
    private HashMap<String,Long> fileUpdateTimes = new HashMap<>();
    GroovyClassLoader loader = new GroovyClassLoader();

    private int testId;

    @Override
    public void update() {
        List<String> localScriptPath = GroovyUpdateContext.localScriptPath;
        if(localScriptPath==null || localScriptPath.isEmpty()){
            log.error("脚本路径未设置，无法加载groovy脚本！");
            return;
        }
        List<String> fileNames = new ArrayList<>();
        for (String s : localScriptPath) {
            if(s.isEmpty()){
                continue;
            }
            fileNames.addAll(FileUtils.findFiles(s, (fileName) -> fileName.endsWith(".groovy")));
        }

        if(fileNames.isEmpty()){
            log.info("无groovy脚本可检测");
            return;
        }
        //全部加载
        if(firsetUpdate){
            log.info("脚本全部加载中。。。");
            loadScripts(fileNames);
//            testScript();
            firsetUpdate = false;
            return;
        }

        List<String> changedFiles = new ArrayList<>();
        //监听变化的脚本
        for (String fileName : fileNames) {
            File file =  Paths.get(fileName).toFile();
            long lastModified = file.lastModified();
            Long oldTime = fileUpdateTimes.get(fileName);
            if(oldTime!=lastModified){
                changedFiles.add(fileName);
            }
        }
        loadScripts(changedFiles);
//        testScript();
    }

    private void testScript() {
        IScript script = GameReqScriptManager.getInstance().getScript(testId);
        if(script!=null){
            script.execute();
        }
    }

    public void loadScripts(List<String> fileNames){
        for (String fileName : fileNames) {
            try {
                File file = Paths.get(fileName).toFile();
                Class aClass = loader.parseClass(file);
                if(aClass==null || !IScript.class.isAssignableFrom(aClass) ){
                    continue;
                }
                //TODO 解析此脚本类
                Annotation annotation = aClass.getAnnotation(GameRequestMapping.class);
                if(annotation==null){
                    continue;
                }
                GameRequestMapping gameAnnoation = (GameRequestMapping) annotation;
                String value = gameAnnoation.value();
                if(value==null || value.isEmpty()){
                    log.error(aClass.getSimpleName()+" 未配置请求路径！跳过收集");
                    continue;
                }
                IScript script;
                try {
                    script = (IScript) aClass.newInstance();
                    //给脚本注入spring容器中的对象
                    autowireScripts(script);
                } catch (Exception e) {
                    e.printStackTrace();
                    continue;
                }
                if(testId==0){
                    testId=value.hashCode();
                }
                log.info("加载到脚本："+aClass.getName());
                GameReqScriptManager.getInstance().addScript(value.hashCode(),value,script);
                fileUpdateTimes.put(fileName,file.lastModified());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



    private static class ScriptMeta{
        private String fileName;
        private String hash;
        private long lastUpdateTime;
    }
}
